﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using FlatRedBall;
using FlatRedBall.Graphics;
using FlatRedBall.Graphics.Animation;
using FlatRedBall.Input;
using FlatRedBall.Math.Geometry;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using BulletHellBoxes.Utilities;

namespace BulletHellBoxes.GameObjects.Player
{
    public class Player : GameObject
    {
        #region Fields
        private GameController _controller;
        private ActiveRole _activeRole;
        private Attacker _attacker;
        private Defender _defender;
        private Text _scoreText;
        private int _score;
        private int _playerNum;
        #endregion

        #region Constants
        private const float START_X_POS = -25.0f;
        private const float START_Y_POS = 14.0f;
        private const float OFFSET = 11.0f;
        #endregion

        #region Properties
        public Circle AttackerCollision
        {
            get { return _attacker.Collision; }
        }

        public AxisAlignedRectangle DefenderCollision
        {
            get { return _defender.Collision; }
        }

        public ActiveRole Role
        {
            get { return _activeRole; }
        }
        #endregion

        #region Constructor
        public Player(bool player, int num)
        {
            PATH = @"Content/GameObjects/Player/P" + num + "/";
            NUM_FRAMES = 1;
            FRAME_TIME = 0.06f; 

            // true = player 1; false = player 2
            _activeRole = player ? ActiveRole.Attacker : ActiveRole.Defender;
            _playerNum = num;
            bool isRight = ((_playerNum - 1) % 2 == 1);
            _controller = new GameController(((_playerNum - 1) / 2), isRight);

            Initialize();
        }

        #endregion

        #region Private Methods
        protected override void Initialize()
        {
            base.Initialize();

            _sprite.RelativeX = START_X_POS + (OFFSET * (_playerNum - 1));
            _sprite.RelativeY = START_Y_POS;

            // Create new Attacker Role
            _attacker = new Attacker(_controller, _playerNum);
            _attacker.AttachTo(this, false);

            // Create new Defender Role
            _defender = new Defender(_controller, _playerNum);
            _defender.AttachTo(this, false);

            _score = 0;
            _scoreText = TextManager.AddText(_score.ToString(), GameProperties.CustomFont);
            _scoreText.AttachTo(_sprite, false);
            _scoreText.RelativeX = 4.0f;
            // Set the default active role based on player number
            SetRole();
        }

        private void SetRole()
        {
            if (_activeRole == ActiveRole.Attacker)
            {
                _defender.Visible = false;
                _attacker.Visible = true;

                _attacker.Reset();

                _attacker.RelativeVelocity = Vector3.Zero;
            }
            else
            {
                _defender.Visible = true;
                _attacker.Visible = false;

                _defender.Reset();

                _attacker.RelativeVelocity = Vector3.Zero;
            }

        }

        public void Reset()
        {
            _attacker.Reset();
            _defender.Reset();
        }
        #endregion

        #region Staple Methods
        public override void Activity()
        {
            if (!Paused)
            {
                _controller.Update();
                ButtonState bs = _controller.TriggerButton;
                Vector2 stickPos = _controller.Stick.Position;
                double stickAngle = _controller.Stick.Angle;
                if (_activeRole == ActiveRole.Attacker)
                {
                    _attacker.Activity(bs, stickPos);
                }
                else if (_activeRole == ActiveRole.Defender)
                {
                    _defender.Activity(bs, stickPos, stickAngle);
                }

                _scoreText.DisplayText = _score.ToString();
            }
        }

        public override void Destroy()
        {
            base.Destroy();
            _attacker.Destroy();
            _defender.Destroy();
        }

        public CollisionType CollideWith(Player p)
        {
            // Check collisions if Player p is currently the attacker.
            CollisionType collide = CollisionType.None;
            if (p.Role == ActiveRole.Attacker)
            {
                // check collision with the win zone aka the Defender
                collide = _defender.CollideZone(p.AttackerCollision);
                if (collide == CollisionType.Win)
                {
                    return collide;
                }
                else
                {
                    // check collision with the bullets.
                    collide = _defender.CollideBullet(p.AttackerCollision);
                    return collide;
                }
            }

            // returns no collision
            return collide;
        }
        #endregion

        #region Public Methods
        public void UpdateScore(bool gainPoint)
        {
            if (gainPoint)
            {
                _score++;
            }

            Reset();
        }

        public void SwapRole()
        {
            Reset();
            _activeRole = (_activeRole == ActiveRole.Attacker) ? ActiveRole.Defender : ActiveRole.Attacker;
            SetRole();
        }

        #endregion

    }
}
